package com.zzwx.controller.context;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.zzwx.dao.entity.sys.User;
import com.zzwx.service.UserService;

/**
 * <ul>
 * <li>Realm：域，Shiro从从Realm获取安全数据（如用户、角色、权限）</li>
 * <li>SecurityManager要验证用户身份，那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法</li>
 * <li>也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作；可以把Realm看成DataSource，即安全数据源</li>
 * </ul>
 * <ul>
 * <li>AuthorizingRealm 的父类有：AuthenticatingRealm（即身份验证）CachingRealm（带有缓存实现）</li>
 * </ul>
 * 
 * @author rono
 */
public class CustomerUserRealm extends AuthorizingRealm {
	private static final Logger logger = LoggerFactory
			.getLogger(CustomerUserRealm.class);
	@Autowired
	UserService userService;

	/**
	 * 初始化加密认证机制
	 */
	public CustomerUserRealm() {
		super.setAuthenticationCachingEnabled(false);
		// 授权
		super.setAuthorizationCacheName("authorizationCache");
		HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(
				"MD5");
		credentialsMatcher.setHashIterations(2); // 两次加密
		credentialsMatcher.setStoredCredentialsHexEncoded(true);
		setCredentialsMatcher(credentialsMatcher);
	}

	/**
	 * 身份认证/登录
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		final String userName = (String) token.getPrincipal(); // principals：身份，即主体的标识属性，可以是任何东西，如用户名、邮箱等
		try {
			User admin = userService.findUserByName(userName);
			Session session = SecurityUtils.getSubject().getSession();
			SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
					userName, // 用户名
					admin.getPassword(), // 密码
					// ByteSource.Util.bytes(admin.getSalt()),//salt =
					// username+salt
					getName() // realm name
			);
			session.setAttribute(WebConstance.CURRENT_USER, admin);
			return authenticationInfo;
		} catch (Exception e) {
			e.printStackTrace();
			logger.debug("用户查询出错");
			throw new AuthenticationException("用户查询出错");
		}
	}

	/**
	 * 授权，即权限验证，验证某个已认证的用户是否拥有某个权限
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		Set<String> roleStrings = new HashSet<String>();
		Set<String> permissionStrings = new HashSet<String>();

		permissionStrings.add("test:view");

		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setRoles(roleStrings);
		authorizationInfo.setStringPermissions(permissionStrings);

		return authorizationInfo;
	}
}